package com.yby6.common.utils;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Collections;
import java.util.LinkedList;

/**
 * 图片工具类
 *
 * @author chupengtang
 */
public class ImageUtil {

    // 水印透明度
    private static float alpha = 0.7f;
    // 水印字体颜色
    private static Color color = Color.red;
    // 字体大小
    private static int fontSize = 35;
    // 水印文字字体
    private static Font font = new Font("宋体", Font.BOLD, fontSize);
    // 水印横向位置
    private static int positionWidth = 30;

    private static final int space = 20;

    public static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }
    /**
     * 获取水印文字总长度
     *
     * @param waterMarkContent 水印的文字
     * @param g                绘图方法
     * @return 水印文字总长度
     */
    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }
    /**
     * 绘制文字水印
     *
     * @param file 文件
     */
    public static InputStream markImageByText(MultipartFile file, String... content) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            // 1、获取源图片
            Image srcImg = ImageIO.read(file.getInputStream());
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null),
                    BufferedImage.TYPE_INT_RGB);
            int height = srcImg.getHeight(null); // 得到源图长
            int width = srcImg.getWidth(null);
            System.out.println("宽度"+width+",高度"+height);
            // 控制图片大小 更改文字大小 15
            fontSize = width / 300 * 15;
            font = new Font("宋体", Font.BOLD, fontSize);
            Graphics2D g = buffImg.createGraphics();// 2、获取画笔对象

            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);// 3、设置对线段的锯齿状边缘处理
            g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0,
                    0, null);
            g.setColor(color); // 5、设置水印文字颜色
            g.setFont(font);// 6、设置水印文字Font
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));// 7、设置水印文字透明度
            // 8、计算文字宽度是否超出图片 进行 换行
            LinkedList<String> waterMarkContentList = new LinkedList<>();
            // 将换行后的文字放入新的集合
            for (String markContent : content) {
                // 单字符长度
                int tempCharLen = 0;
                // 单行字符总长度临时计算
                int tempLineLen = 0;
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < markContent.length(); i++) {
                    char tempChar = markContent.charAt(i);
                    tempCharLen = getCharLen(tempChar, g);
                    tempLineLen += tempCharLen;
                    // 文字长度大于图片宽度-2*间距-字体大小
                    if (tempLineLen > width - positionWidth * 2 - tempCharLen) {
                        // 长度已经满一行
                        waterMarkContentList.add(sb.toString());
                        // 清空内容,重新追加
                        sb.delete(0, sb.length());
                        tempLineLen = 0;
                    }
                    // 追加字符
                    sb.append(tempChar);
                }
                waterMarkContentList.add(sb.toString());
            }
            Collections.reverse(waterMarkContentList);
            for (int i = 0; i < waterMarkContentList.size(); i++) {
                // 8.1 、第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y)
                g.drawString(waterMarkContentList.get(i), positionWidth, height - (i * fontSize) - ((i + 1) * 100));
            }
            // 9、释放资源
            g.dispose();
            ImageIO.write(buffImg, "jpg", os);
            InputStream inputStream = new ByteArrayInputStream(os.toByteArray());
            return inputStream;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 绘制文字水印
     *
     * @param file
     * @param filePath
     * @param content
     * @return
     */
    public static boolean markImageByText(MultipartFile file, String filePath, String... content) {
        OutputStream os = null;
        try {
            // 1、获取源图片
            Image srcImg = ImageIO.read(file.getInputStream());
            BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null),
                    BufferedImage.TYPE_INT_RGB);
            int height = srcImg.getHeight(null); // 得到源图长

            Graphics2D g = buffImg.createGraphics();// 2、获取画笔对象

            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);// 3、设置对线段的锯齿状边缘处理
            g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0,
                    0, null);
            g.setColor(color); // 5、设置水印文字颜色
            g.setFont(font);// 6、设置水印文字Font
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));// 7、设置水印文字透明度
            // 8、第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y)
            for (int i = 0; i < content.length; i++) {
                g.drawString(content[i], positionWidth, height - (i * fontSize) - ((i + 1) * 20));
            }
            // 9、释放资源
            g.dispose();
            os = new FileOutputStream(filePath);
            ImageIO.write(buffImg, "jpg", os);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}
